import { post, get, del, BASE_URL } from './request';

/**
 * WebSocket管理器，用于管理WebSocket连接和消息处理
 * 适配UniApp环境，使用uni.connectSocket API
 */
class WebSocketManager {
  constructor() {
    this.socketTask = null; // 改为socketTask存储uni.connectSocket返回的对象
    this.sessionId = null;
    this.callbacks = new Map();
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectDelay = 1000;
    this.isConnecting = false;
    this.reconnectTimer = null;
    this.wsUrl = null;
  }

  /**
   * 建立WebSocket连接
   * @param {Function} onConnect - 连接成功回调
   * @param {Function} onError - 错误回调
   */
  connect(onConnect, onError) {
    // 从BASE_URL获取服务器地址，将http改为ws
    this.wsUrl = BASE_URL.replace('http', 'ws') + '/websocket'; // 与后端配置端点完全匹配
    
    if (this.isConnecting) {
      console.log('WebSocket连接请求正在进行中...');
      return;
    }
    
    this.isConnecting = true;
    
    try {
      console.log('尝试连接WebSocket服务器:', this.wsUrl);
      
      // 使用uni.connectSocket替代原生WebSocket构造函数
      this.socketTask = uni.connectSocket({
        url: this.wsUrl,
        header: {
          'content-type': 'application/json',
          'X-Client-ID': 'star-mate-frontend' // 添加客户端标识，后端可以通过拦截器获取
        },
        success: () => {
          console.log('WebSocket连接请求已发送到服务器');
        },
        fail: (error) => {
          console.error('WebSocket连接请求发送失败:', JSON.stringify(error));
          this.isConnecting = false;
          onError && onError(error);
        }
      });
      
      // 设置连接打开事件监听
      this.socketTask.onOpen(() => {
        console.log('WebSocket连接已成功建立!');
        this.isConnecting = false;
        this.reconnectAttempts = 0;
        // 发送连接确认消息
        this.send({ type: 'connect', message: 'Hello, Server!' });
        onConnect && onConnect();
      });
      
      // 设置接收消息事件监听
      this.socketTask.onMessage((res) => {
        try {
          console.log('收到WebSocket消息:', res.data);
          const data = JSON.parse(res.data);
          this.handleMessage(data);
        } catch (error) {
          console.error('解析WebSocket消息失败:', error, '原始消息:', res.data);
        }
      });
      
      // 设置连接关闭事件监听
      this.socketTask.onClose((res) => {
        console.log('WebSocket连接已关闭，关闭状态码:', res.code, '原因:', res.reason);
        this.isConnecting = false;
        this.socketTask = null;
        this.attemptReconnect();
      });
      
      // 设置错误事件监听
      this.socketTask.onError((error) => {
        console.error('WebSocket发生错误:', JSON.stringify(error));
        this.isConnecting = false;
        onError && onError(error);
      });
    } catch (error) {
      console.error('创建WebSocket连接异常:', error);
      this.isConnecting = false;
      onError && onError(error);
    }
  }

  /**
   * 尝试重新连接
   */
  attemptReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
      console.log(`尝试第${this.reconnectAttempts}次重连，延迟${delay}ms`);
      
      this.reconnectTimer = setTimeout(() => {
        this.connect();
      }, delay);
    } else {
      console.error('WebSocket重连次数已达上限');
    }
  }

  /**
   * 发送消息
   * @param {Object} message - 消息对象
   */
  send(message) {
    if (!this.socketTask) {
      throw new Error('WebSocket连接未建立');
    }
    
    // 使用uni.sendSocketMessage发送消息
    uni.sendSocketMessage({
      data: JSON.stringify(message),
      success: () => {
        console.log('WebSocket消息发送成功');
      },
      fail: (error) => {
        console.error('WebSocket消息发送失败:', error);
        throw error;
      }
    });
  }

  /**
   * 处理接收到的消息
   * @param {Object} data - 消息数据
   */
  handleMessage(data) {
    // 处理连接成功消息，保存sessionId
    if (data.type === 'connection') {
      this.sessionId = data.connectionId;
      console.log('获取到WebSocket会话ID:', this.sessionId);
    }
    
    // 根据消息类型调用对应的回调
    if (this.callbacks.has(data.type)) {
      const callbacks = this.callbacks.get(data.type);
      callbacks.forEach(callback => {
        try {
          callback(data);
        } catch (error) {
          console.error('执行回调函数失败:', error);
        }
      });
    }
    
    // 同时根据event字段调用对应的回调（支持workflow_finished等事件）
    if (data.event && this.callbacks.has(data.event)) {
      const callbacks = this.callbacks.get(data.event);
      callbacks.forEach(callback => {
        try {
          callback(data);
        } catch (error) {
          console.error('执行event回调函数失败:', error);
        }
      });
    }
    
    // 触发通用消息事件，确保前端能接收到所有消息
    if (this.callbacks.has('message')) {
      const callbacks = this.callbacks.get('message');
      callbacks.forEach(callback => {
        try {
          callback(data);
        } catch (error) {
          console.error('执行message回调函数失败:', error);
        }
      });
    }
  }

  /**
   * 注册消息回调
   * @param {string} messageType - 消息类型
   * @param {Function} callback - 回调函数
   */
  on(messageType, callback) {
    if (!this.callbacks.has(messageType)) {
      this.callbacks.set(messageType, new Set());
    }
    this.callbacks.get(messageType).add(callback);
    
    // 返回取消注册函数
    return () => {
      this.off(messageType, callback);
    };
  }

  /**
   * 取消注册消息回调
   * @param {string} messageType - 消息类型
   * @param {Function} callback - 回调函数
   */
  off(messageType, callback) {
    if (this.callbacks.has(messageType)) {
      this.callbacks.get(messageType).delete(callback);
      if (this.callbacks.get(messageType).size === 0) {
        this.callbacks.delete(messageType);
      }
    }
  }

  /**
   * 关闭WebSocket连接
   */
  close() {
    // 清除重连定时器
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    
    // 关闭WebSocket连接
    if (this.socketTask) {
      uni.closeSocket();
      this.socketTask = null;
    }
    
    // 重置状态
    this.sessionId = null;
    this.callbacks.clear();
    this.isConnecting = false;
  }

  /**
   * 获取WebSocket连接状态
   * @returns {string} WebSocket连接状态描述
   */
  getReadyState() {
    // uni.connectSocket不支持直接获取readyState，返回描述性状态
    if (!this.socketTask) {
      return 'CLOSED';
    }
    if (this.isConnecting) {
      return 'CONNECTING';
    }
    return 'OPEN'; // 简化处理，实际可能需要更复杂的状态管理
  }

  /**
   * 获取当前会话ID
   * @returns {string} 会话ID
   */
  getSessionId() {
    return this.sessionId;
  }
}

// 创建WebSocket管理器单例
const wsManager = new WebSocketManager();

/**
 * 对话模块API - 仅保留核心功能
 * 提供对话相关的接口调用功能
 */
const chatApi = {
  /**
   * 获取会话列表
   * @param {Object} params - 查询参数
   * @param {string} params.user - 用户标识（必需）
   * @param {number} params.limit - 限制数量
   * @param {string} params.last_id - 分页标记
   * @returns {Promise} - 返回会话列表数据
   */
  getConversations: (params = {}) => {
    // 确保params是一个对象
    if (!params || typeof params !== 'object') {
      console.error('getConversations: params必须是一个对象');
      throw new Error('参数格式错误');
    }
    
    // 确保user参数存在且不为空
    if (!params.user || params.user.trim() === '') {
      console.error('getConversations: user参数缺失或为空');
      throw new Error('用户参数缺失');
    }
    
    // 创建一个新的参数对象，避免修改原始对象
    const requestParams = { ...params };
    
    // 确保user参数是字符串类型
    if (typeof requestParams.user !== 'string') {
      requestParams.user = String(requestParams.user);
      console.warn('getConversations: user参数不是字符串，已转换');
    }
    
    // 记录请求参数，特别强调user参数
    console.log('调用getConversations，参数:', JSON.stringify(requestParams));
    console.log('特别强调 - user参数值:', requestParams.user);
    
    // 确保所有字符串参数都不为空
    Object.keys(requestParams).forEach(key => {
      if (typeof requestParams[key] === 'string' && requestParams[key].trim() === '') {
        console.warn(`getConversations: 参数${key}是空字符串`);
      }
    });
    
    // 直接使用传入的参数调用get方法
    return get('/api/conversations', requestParams)
      .catch(error => {
        console.error('getConversations请求失败:', error);
        // 重新抛出错误，保留原始错误信息
        throw error;
      });
  },

  /**
   * 获取消息历史记录
   * @param {string} conversationId - 会话ID
   * @param {Object} params - 查询参数
   * @param {number} params.page - 页码，默认1
   * @param {number} params.pageSize - 每页数量，默认20
   * @param {number} params.beforeTime - 加载此时间之前的消息
   * @returns {Promise} - 返回消息列表数据
   */
  getMessages: (conversationId, params = {}) => {
    const defaultParams = {
      page: 1,
      pageSize: 20,
      ...params
    };
    return get(`/api/chat/conversations/${conversationId}/messages`, defaultParams);
  },

  /**
   * 获取会话历史消息（新版接口）
   * @param {Object} params - 查询参数
   * @param {string} params.user - 用户名
   * @param {string} params.conversation_id - 会话ID
   * @param {number} params.limit - 返回消息数量限制，默认40
   * @returns {Promise} - 返回会话历史消息数据
   */
 getConversationHistory: (params) => {
    const defaultParams = {
      user: '',
      limit: 40,
      ...params
    };
    
    // 只有当conversation_id不为空且非空字符串时才包含在请求参数中
    if (!defaultParams.conversation_id || defaultParams.conversation_id.trim() === '') {
      delete defaultParams.conversation_id;
      console.log('会话ID为空，不包含在请求参数中');
    } else {
      console.log('使用提供的会话ID:', defaultParams.conversation_id);
    }
    
    return get('/api/messages/history', defaultParams);
  },

  /**
   * 发送消息
   * @param {string} conversationId - 会话ID
   * @param {Object} data - 消息数据
   * @param {string} data.type - 消息类型：text
   * @param {string} data.content - 消息内容
   * @returns {Promise} - 返回发送的消息数据
   */
  sendMessage: (conversationId, data) => {
    return post(`/api/chat/conversations/${conversationId}/messages`, data);
  },

  /**
   * 发送聊天消息（重构版）
   * @param {Object} params - 消息参数
   * @param {Function} onChunk - 接收数据块的回调函数（仅在streaming模式下使用）
   * @param {Function} onComplete - 完成回调函数（仅在streaming模式下使用）
   * @param {Function} onError - 错误回调函数
   * @returns {Promise} - 返回响应结果
   */
  sendChatMessage: async (params, onChunk, onComplete, onError) => {
    try {
      // 记录发送消息的日志
      console.log('调用sendChatMessage，参数:', params);
      
      // 构建默认参数对象，包含所有必要字段
      const defaultParams = {
        user: params.user || '',
        conversation_id: params.conversation_id || '',
        query: params.query || '',
        inputs: params.inputs || {},
        auto_generate_name: params.auto_generate_name !== undefined ? params.auto_generate_name : true,
        response_mode: params.response_mode || 'streaming'
      };
      
      // 确保inputs是对象类型
      if (!defaultParams.inputs || typeof defaultParams.inputs !== 'object') {
        defaultParams.inputs = {};
      }
      
      // 处理files参数（可选）
      if (params.files && params.files.length > 0) {
        defaultParams.files = params.files;
        console.log('发送消息：包含文件，文件数量:', params.files.length);
      } else {
        console.log('发送消息：不包含文件');
      }
      
      // 处理conversation_id参数
      if (!defaultParams.conversation_id || defaultParams.conversation_id.trim() === '') {
        delete defaultParams.conversation_id;
        console.log('发送消息：会话ID为空，将创建新会话');
      } else {
        console.log('发送消息：使用提供的会话ID:', defaultParams.conversation_id);
      }
      
      // 根据response_mode选择发送方式
      if (defaultParams.response_mode === 'streaming') {
        console.log('使用流式模式发送消息');
        // 使用WebSocket发送流式消息
        return chatApi.sendStreamingChatMessage(defaultParams, onChunk, onComplete, onError);
      } else {
        console.log('使用阻塞模式发送消息');
        // 使用HTTP POST发送阻塞消息
        return post('/v1/chat-messages', defaultParams);
      }
    } catch (error) {
      console.error('发送聊天消息失败:', error);
      // 调用错误回调
      if (onError) {
        onError(error);
      }
      throw error;
    }
  },

  /**
   * 发送流式聊天消息
   * @param {Object} params - 消息参数
   * @param {Function} onChunk - 接收数据块的回调函数
   * @param {Function} onComplete - 完成回调函数
   * @param {Function} onError - 错误回调函数
   * @returns {Promise} - 返回发送的消息数据
   */
  sendStreamingChatMessage: async (params, onChunk, onComplete, onError) => {
    try {
      // 确保使用streaming模式
      const streamingParams = {
        ...params,
        response_mode: 'streaming'
      };
      
      // 创建一个Promise来处理WebSocket连接和消息响应
      return new Promise((resolve, reject) => {
        // 连接WebSocket
        wsManager.connect(
          () => {
            console.log('WebSocket连接成功，准备发送消息');
            
            // 生成唯一的消息ID用于跟踪响应
            const messageId = `msg-${Date.now()}`;
            const taskId = `task-${Date.now()}`;
            // 不再前端生成会话ID，使用后端从外部API返回的会话ID
            const conversationId = params.conversation_id || null;
            console.log('发送流式消息：会话ID值为:', conversationId);
            
            // 注册消息响应回调 - 处理'response'类型
            const unsubscribeResponse = wsManager.on('response', (data) => {
              if (onChunk) {
                onChunk({
                  data: {
                    outputs: {
                      answer: data.message || data.content
                    }
                  },
                  conversation_id: data.conversation_id || conversationId,
                  event: 'partial_response'
                });
              }
            });
            
            // 注册消息响应回调 - 监听message_chat事件（根据websocket.js的实现，会根据data.type触发）
            const unsubscribeMessage = wsManager.on('message_chat', (data) => {
              if (onChunk) {
                // 处理message事件类型的数据，保留所有重要字段
                if (data.event === 'message') {
                  onChunk({
                    data: {
                      outputs: {
                        answer: data.answer || data.message || data.content
                      }
                    },
                    conversation_id: data.conversation_id,
                    message_id: data.message_id,
                    task_id: data.task_id,
                    created_at: data.created_at,
                    user: data.user,
                    query: data.query,
                    inputs: data.inputs,
                    files: data.files,
                    event: 'message' // 保留原始事件类型
                  });
                } else if (data.event !== 'complete') { // 处理其他非complete类型的消息
                  onChunk({
                    data: {
                      outputs: {
                        answer: data.answer || data.message || data.content
                      }
                    },
                    conversation_id: data.conversation_id,
                    event: 'partial_response'
                  });
                }
              }
            });
            
            // 注册workflow_finished事件监听器
            const unsubscribeWorkflowFinished = wsManager.on('workflow_finished', (data) => {
              // 提取嵌套的data.outputs.answer结构
              const answer = data.data?.outputs?.answer || data.answer || '';
              
              // 可以选择在onChunk中处理完整响应，或者在onComplete中处理
              if (onChunk) {
                onChunk({
                  data: {
                    outputs: {
                      answer: answer
                    },
                    id: data.data?.id || data.message_id,
                    status: data.data?.status || 'succeeded'
                  },
                  conversation_id: data.conversation_id,
                  message_id: data.message_id,
                  task_id: data.task_id,
                  created_at: data.created_at,
                  event: 'workflow_finished'
                });
              }
            });
            
            // 保留通用message事件监听作为兜底
            const unsubscribeGenericMessage = wsManager.on('message', (data) => {
              if (onChunk && data.type !== 'chat') { // 避免重复处理chat类型消息
                // 如果是message事件类型，保留所有字段
                if (data.event === 'message') {
                  onChunk({
                    data: {
                      outputs: {
                        answer: data.answer || data.message || data.content
                      }
                    },
                    conversation_id: data.conversation_id,
                    message_id: data.message_id,
                    task_id: data.task_id,
                    created_at: data.created_at,
                    user: data.user,
                    query: data.query,
                    inputs: data.inputs,
                    files: data.files,
                    event: 'message' // 保留原始事件类型
                  });
                } else {
                  // 处理其他类型的通用消息
                  onChunk({
                    data: {
                      outputs: {
                        answer: data.answer || data.message || data.content
                      }
                    },
                    conversation_id: data.conversation_id,
                    event: 'partial_response'
                  });
                }
              }
            });
            
            const unsubscribeComplete = wsManager.on('complete', (data) => {
              // 清理回调
              unsubscribeResponse();
              unsubscribeMessage();
              unsubscribeGenericMessage();
              unsubscribeWorkflowFinished();
              unsubscribeComplete();
              unsubscribeError();
              
              // 使用从workflow_finished事件中可能已经获取到的数据，或者使用默认值
              const response = {
                data: {
                  outputs: {
                    answer: data.content || data.message || ''
                  },
                  status: 'succeeded'
                },
                conversation_id: data.conversation_id || conversationId,
                message_id: data.message_id || messageId,
                task_id: data.task_id || taskId,
                event: 'workflow_finished'
              };
              
              if (onComplete) {
                onComplete(response);
              }
              
              resolve(response);
            });
            
            const unsubscribeError = wsManager.on('error', (errorData) => {
              // 清理回调
              unsubscribeResponse();
              unsubscribeMessage();
              unsubscribeGenericMessage();
              unsubscribeWorkflowFinished();
              unsubscribeComplete();
              unsubscribeError();
              
              const error = new Error(errorData.message || 'WebSocket通信错误');
              
              if (onError) {
                onError(error);
              }
              
              reject(error);
            });
            
            // 发送消息到服务器
            try {
              // 调试日志，确认params.user的值
              console.log('准备发送的消息参数:', { user: params.user, conversation_id: conversationId });
              
              // 构建完整的WebSocket消息，包含所有必要参数
              const message = {
                type: 'chat',
                query: params.query, // 使用query而不是content，保持与HTTP API一致
                message_id: messageId,
                timestamp: Date.now(),
                user: params.user || 'user', // 确保user字段存在
                inputs: params.inputs || {}, // 添加inputs字段
                auto_generate_name: params.auto_generate_name !== undefined ? params.auto_generate_name : true, // 添加自动生成名称选项
                response_mode: 'streaming' // 确保是流式模式
              };
              
              // 只有当conversationId不为空且非空字符串时才添加到消息中
              if (conversationId && conversationId.trim() !== '') {
                message.conversation_id = conversationId;
                console.log('WebSocket消息：包含会话ID:', conversationId);
              } else {
                console.log('WebSocket消息：未包含会话ID，将创建新会话');
              }
              
              // 可选处理files参数
              if (params.files && params.files.length > 0) {
                message.files = params.files;
                console.log('WebSocket消息：包含文件，数量:', params.files.length);
              }
              
              wsManager.send(message);
              console.log('WebSocket消息已发送:', message);
            } catch (error) {
              console.error('发送WebSocket消息失败:', error);
              
              // 清理回调
              unsubscribeResponse();
              unsubscribeMessage();
              unsubscribeGenericMessage();
              unsubscribeWorkflowFinished();
              unsubscribeComplete();
              unsubscribeError();
              
              if (onError) {
                onError(error);
              }
              
              reject(error);
            }
          },
          (error) => {
            console.error('WebSocket连接失败:', error);
            
            if (onError) {
              onError(error);
            }
            
            reject(error);
          }
        );
      });
    } catch (error) {
      console.error('发送流式聊天消息失败:', error);
      if (onError) {
        onError(error);
      }
      throw error;
    }
  },
  
  /**
   * 获取智能体参数
   * @returns {Promise} - 返回智能体参数，包含开场白等信息
   */
  getAgentParameters: () => {
    return get('/api/messages/parameters');
  },

  /**
   * 获取文件上传凭证
   * @param {string} fileType - 文件类型
   * @param {string} fileName - 文件名
   * @returns {Promise} - 返回上传凭证
   */
  getFileUploadToken: (fileType, fileName) => {
    return post('/api/files/upload/token', {
      file_type: fileType,
      file_name: fileName
    });
  },

  /**
   * 上传文件
   * @param {File} file - 文件对象
   * @param {string} token - 上传凭证
   * @returns {Promise} - 返回上传结果
   */
  uploadFile: async (file, token) => {
    try {
      // 创建FormData对象
      const formData = new FormData();
      formData.append('file', file);
      formData.append('token', token);
      
      // 注意：在实际项目中，这里需要使用正确的文件上传API
      // 由于是模拟环境，我们返回一个模拟的上传结果
      
      // 模拟上传延迟
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // 返回模拟的上传结果
      return {
        success: true,
        data: {
          file_id: `file-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
          file_name: file.name,
          file_size: file.size,
          file_type: file.type || 'application/octet-stream',
          upload_url: `https://example.com/uploads/${file.name}`,
          created_at: Date.now()
        }
      };
    } catch (error) {
      console.error('上传文件失败:', error);
      throw error;
    }
  },

  /**
   * 获取文件信息
   * @param {string} fileId - 文件ID
   * @returns {Promise} - 返回文件信息
   */
  getFileInfo: (fileId) => {
    return get(`/api/files/${fileId}`);
  },
  
  /**
   * 删除会话
   * @param {string} conversationId - 会话ID
   * @param {Object} params - 删除参数
   * @param {string} params.user - 用户名
   * @returns {Promise} - 返回删除结果
   */
  deleteConversation: (conversationId, params = {}) => {
    // 确保params是一个对象
    if (!params || typeof params !== 'object') {
      console.error('deleteConversation: params必须是一个对象');
      throw new Error('参数格式错误');
    }
    
    // 确保user参数存在且不为空
    if (!params.user || params.user.trim() === '') {
      console.error('deleteConversation: user参数缺失或为空');
      throw new Error('用户参数缺失');
    }
    
    console.log('调用deleteConversation，会话ID:', conversationId, '参数:', params);
    return del(`/api/conversations/${conversationId}`, params);
  }
};

export default chatApi;